﻿
//元件引用分析类
namespace n_PyStructLink
{
using System;
using n_PyET;
using n_PyMemberType;
using n_PyParse;
using n_PyParseNet;
using n_PyStructList;
using n_PyStructNode;
using n_PyVarType;

public static class StructLink
{
	static string UnitName;
	
	//获取元件信息,生成: 元件列表 函数列表 变量列表
	public static void Record()
	{
		Parse.DealWith( ref UnitName, new Parse.MemberListHandle( 成员列表 ) );
		
		//查找结构体信息
		StandardStructList();
	}
	
	static void 成员列表( int Index )
	{
		for( int i = 1; i < ParseNet.NodeSet[ Index ].Length; ++i ) {
			int index = int.Parse( ParseNet.NodeSet[ Index ][ i ] );
			
			//判断是否元件定义
			if( ParseNet.NodeSet[ index ][ 0 ] == ParseNet.Node.元件 ) {
				元件( index );
				continue;
			}
			//判断是否连接器定义
			if( ParseNet.NodeSet[ index ][ 0 ] == ParseNet.Node.连接器 ) {
				连接器( index );
				continue;
			}
		}
	}
	
	static void 元件( int Index )
	{
		Parse.Unit( ref UnitName, Index, new Parse.MemberListHandle( 成员列表 ) );
	}
	
	static void 连接器( int Index )
	{
		//提取第一个成员信息
		int FirstIndex = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
		int ErrorIndex1 = 0;
		string FirstName = null;
		Parse.GetMemberNames( UnitName, FirstIndex, ref FirstName, ref ErrorIndex1 );
		
		//提取第二个成员信息
		int SecondIndex = int.Parse( ParseNet.NodeSet[ Index ][ 4 ] );
		int ErrorIndex2 = 0;
		string SecondName = null;
		Parse.GetMemberNames( UnitName, SecondIndex, ref SecondName, ref ErrorIndex2 );
		
		//判断成员是否为结构体类型
		int FirstStructIndex = StructList.GetDirectIndex( FirstName );
		if( FirstStructIndex != -1 ) {
			if( StructList.Get( FirstStructIndex ).RealRefType != MemberType.RealRefType.link ) {
				ET.WriteParseError( ErrorIndex1, "连接器的左端必须为引用类型元件:" + FirstName );
				return;
			}
			StructList.Get( FirstStructIndex ).TargetMemberName = SecondName;
			return;
		}
	}
	
	//查找结构体信息
	public static void StandardStructList()
	{
		int Times = 0;
		bool HaveUnkownAddr;
		do {
			++Times;
			if( Times > 20 ) {
				ET.WriteLineError( 0, 0, "结构体定义的层数过大,或者您的程序中出现结构体的递归定义" );
				return;
			}
			HaveUnkownAddr = false;
			for( int i = 0; i < StructList.length; ++i ) {
				
				//如果当前结构体已经处理,转向下一个
				if( StructList.Get( i ).Size != -1 ) {
					continue;
				}
				int Offset = 0;
				string StoreType = null;
				MemberNode[] MemberList = StructList.Get( i ).MemberList;
				
				//搜索分量信息
				for( int j = 0; j < MemberList.Length; ++j ) {
					
					string Type = MemberList[ j ].Type;
					if( Type == null ) {
						string BaseUnitName = StructList.Get( i ).UnitName;
						Type = Parse.GetType( BaseUnitName, MemberList[ j ].TypeIndex );
						if( Type == null ) {
							return;
						}
						//创建子类型的完整类型
						if( VarType.isBase( Type ) ) {
							Type = VarType.CreatVdataType( VarType.VBase, Type );
						}
						MemberList[ j ].Type = Type;
					}
					int Size = VarType.GetSize( Type );
					
					//如果引用了未处理的结构体,转向下一个
					if( Type.StartsWith( "struct " ) && Size == -1 ) {
						
						//如果未定义的结构体,报错
						string StructName = Type.Split( ' ' )[ 1 ];
						if( StructList.GetIndex( StructName ) == -1 ) {
							ET.WriteParseError( MemberList[ j ].Location,
								"未定义的结构体类型: " + StructName );
							return;
						}
						HaveUnkownAddr = true;
						continue;
					}
					string SType = VarType.GetStoreTypeonce( Type );
					
					//如果是第一个分量,直接存入元件类型
					if( j == 0 ) {
						StoreType = SType;
					}
					//比较存储类型是否和第一个一致
					else {
						if( !VarType.StoreTypeisSame( StoreType, SType ) ) {
							ET.WriteParseError( MemberList[ j ].Location,
								"结构体中的所有成员必须在同一种元件类型中: " +
								StoreType + " <-- " + SType
							);
						}
					}
					MemberList[ j ].Size = Size;
					MemberList[ j ].Offset = Offset;
					Offset += Size;
				}
				StructList.Get( i ).Size = Offset;
				StructList.Get( i ).StoreType = StoreType;
			}
		}
		while( HaveUnkownAddr );
	}
}
}
